package net.poddubnyak.friendlist.web;

import java.util.Map;

import net.poddubnyak.friendlist.domain.User;
import net.poddubnyak.friendlist.service.UserService;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

/**
 * UserController class is a main Controller in this project.
 * 
 * @author Petr Poddubnjak
 */
@Controller
public class UserController {

	/**
	 * Constant for logging.
	 */
	private static final Logger logger = Logger.getLogger(UserController.class);

	/**
	 * UserService bean
	 */
	@Autowired
	private UserService userService;

	/**
	 * Home page
	 * 
	 * @return home view
	 */
	@RequestMapping("/home")
	public String home() {
		return "home";
	}

	/**
	 * Sets home page
	 * 
	 * @return home view
	 */
	@RequestMapping("/")
	public String start() {
		return "home";
	}

	/**
	 * Create userList view
	 * 
	 * @param map
	 *            - map of variables
	 * @return - userList view
	 */
	@RequestMapping("/userList")
	public String listUsers(Map<String, Object> map) {
		logger.info("UserController listUsers method is called.");
		map.put("TopUsers", userService.listTopUsers());
		map.put("userList", userService.listUser());
		return "userList";
	}

	/**
	 * Create groupList view. return all classmates
	 * 
	 * @param map
	 *            - map of variables
	 * @return - groupList view
	 */
	@RequestMapping("/groupList")
	public String listClassmates(Map<String, Object> map) {
		logger.info("UserController listClassmates method is called.");
		String currentUserEmail = SecurityContextHolder.getContext()
				.getAuthentication().getName();
		User currentUser = userService.getUserByEmail(currentUserEmail);
		String groupId = currentUser.getGroupId();
		map.put("groupList", userService.listClassmates(groupId));
		map.put("TopUsers", userService.listTopUsers());
		return "groupList";
	}

	/**
	 * Delete User object
	 * 
	 * @param userId
	 *            - id of deleting user
	 * @return - redirect to userList view
	 */
	@RequestMapping("/removeUser/{userId}")
	public String removeUser(@PathVariable("userId") Integer userId) {
		logger.info("UserController removeUser method is called.");
		userService.removeUser(userId);
		return "redirect:/userList";
	}

	/**
	 * Increase rating of user
	 * 
	 * @param userId
	 *            - id of user wich need to increase rating
	 * @return - redirect to userList view
	 */
	@RequestMapping("/vote/{userId}")
	public String voteUser(@PathVariable("userId") Integer userId) {
		logger.info("UserController voteUser method is called.");
		User user = userService.getUserById(userId);
		user.setRating(user.getRating() + 1);
		userService.updateUser(user);
		return "redirect:/userList";
	}

	/**
	 * Create form for editing of user profile
	 * 
	 * @param map
	 *            - map of variables
	 * @return - editProfile view
	 */
	@RequestMapping(value = "/editProfile", method = RequestMethod.GET)
	public String editProfileForm(Map<String, Object> map) {
		logger.info("UserController editProfileForm method is called.");
		String currentUserEmail = SecurityContextHolder.getContext()
				.getAuthentication().getName();
		map.put("currentUser", userService.getUserByEmail(currentUserEmail));
		return "editProfile";
	}

	/**
	 * Save changes in user profile
	 * 
	 * @param currentUser
	 *            - User object
	 * @param result
	 *            - binding result variable
	 * @return - editProfile view
	 */
	@RequestMapping(value = "/editProfile", method = RequestMethod.POST)
	public String updateProfile(
			@ModelAttribute("currentUser") User currentUser,
			BindingResult result) {
		logger.info("UserController updateProfile method is called.");
		if (result.hasErrors()) {
			return "editProfile";
		} else {
			userService.updateUser(currentUser);
			return "editProfile";
		}
	}

	/**
	 * Gets profile of user by id
	 * 
	 * @param userId
	 *            - id of User object
	 * @param map
	 *            - map of variables
	 * @return - userProfile view
	 */
	@RequestMapping("/profile={userId}")
	public String profileUser(@PathVariable("userId") Integer userId,
			Map<String, Object> map) {
		logger.info("UserController  profileUser method is called.");
		map.put("user", userService.getUserById(userId));
		return "userProfile";
	}

	/**
	 * Create form for registration of new user
	 * 
	 * @param map
	 *            - map of variables
	 * @return - regUser view
	 */
	@RequestMapping(value = "/regUser", method = RequestMethod.GET)
	public String registrationForm(Map<String, Object> map) {
		logger.info("UserController  registrationForm method is called.");
		map.put("user", new User());
		return "regUser";
	}

	/**
	 * Create new user.
	 * 
	 * @param user
	 *            - User object
	 * @param result
	 *            - binding result variable
	 * @return - home view
	 */
	@RequestMapping(value = "/regUser", method = RequestMethod.POST)
	public String submitRegistration(@ModelAttribute("user") User user,
			BindingResult result) {
		logger.info("UserController  submitRegistration method is called.");
		if (result.hasErrors()) {
			return "regUser";
		} else {
			userService.addUser(user);
			return "home";
		}
	}

}
